home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / news / readers / nn / nn6.4.patch3 < prev    next >
Encoding:
Text File  |  1990-05-21  |  53.7 KB  |  1,990 lines

  1.          This is an official patch to nn release 6.4
  2.          -------------------------------------------
  3.  
  4.                    PATCH #3
  5.  
  6.                 Priority: HIGH
  7.  
  8.  
  9. These patches fix more bugs in the 6.4 release.  A major bug related
  10. to rmgroup'ing one group resulting in another group being dropped from
  11. the database has been solved.  The problems related to unsubscribing
  12. to the last group in the presentation sequence are also solved.
  13.  
  14. All changes are described in the updated RELEASE_NOTES file (read that
  15. for details about this patch).  Thanks to all who reported bugs and
  16. provided fixes.
  17.  
  18. To apply this patch, use nn's :patch command, or run this command from
  19. the shell in the root of the nn source tree:
  20.     patch -p0 < this-article
  21.  
  22.  
  23. ++Kim Storm
  24.  
  25. *** ./LAST/active.c    Sat May  5 13:37:31 1990
  26. --- active.c    Mon May 21 12:01:08 1990
  27. ***************
  28. *** 16,23 ****
  29.       int must_update;
  30.       register flag_type old_flag;
  31.       
  32. !     Loop_Groups_Header(gh)
  33.       gh->master_flag &= ~M_VALID;
  34.   
  35.       while (fgets(line, 512, act)) {
  36.       if (copy != NULL) fputs(line, copy);
  37. --- 16,26 ----
  38.       int must_update;
  39.       register flag_type old_flag;
  40.       
  41. !     Loop_Groups_Header(gh) {
  42.       gh->master_flag &= ~M_VALID;
  43. +     gh->first_a_article = 0;
  44. +     gh->last_a_article = 0;
  45. +     }
  46.   
  47.       while (fgets(line, 512, act)) {
  48.       if (copy != NULL) fputs(line, copy);
  49. *** ./LAST/admin.c    Wed May 16 11:22:33 1990
  50. --- admin.c    Mon May 21 13:45:45 1990
  51. ***************
  52. *** 262,267 ****
  53. --- 262,269 ----
  54.   
  55.       data = ix = NULL;
  56.   
  57. +     if (gh->master_flag & M_IGNORE_GROUP) return 1;
  58.       if (gh->first_db_article == (gh->last_db_article + 1)
  59.       && gh->index_write_offset == 0)
  60.       return 1;
  61. ***************
  62. *** 419,426 ****
  63.       article_number first_article;
  64.       int n;
  65.   
  66. !     if (init_group(gh) <= 0)
  67.       printf("cannot access group %s\n", gh->group_name);
  68.   
  69.       update_group(gh);
  70.   
  71. --- 421,430 ----
  72.       article_number first_article;
  73.       int n;
  74.   
  75. !     if (init_group(gh) <= 0) {
  76.       printf("cannot access group %s\n", gh->group_name);
  77. +     return 0;
  78. +     }
  79.   
  80.       update_group(gh);
  81.   
  82. ***************
  83. *** 515,520 ****
  84. --- 519,525 ----
  85.    err:
  86.       if (data != NULL) fclose(data);
  87.       if (ix != NULL) fclose(ix);
  88. +     if (gh->master_flag & M_IGNORE_GROUP) return 0;
  89.       printf("\n*** DATABASE INCONSISTENCY DETECTED - run V)alidate\n");
  90.       return 0;
  91.   }
  92. *** ./LAST/answer.c    Wed May 16 11:23:33 1990
  93. --- answer.c    Fri May 18 22:26:05 1990
  94. ***************
  95. *** 105,112 ****
  96.   FILE *t;
  97.   int use_follow;
  98.   {
  99. !     fprintf(t, "Newsgroups: %s\n",
  100. !         use_follow && news.ng_follow ? news.ng_follow : news.ng_groups);
  101.       ed_line++;
  102.   }
  103.   
  104. --- 105,116 ----
  105.   FILE *t;
  106.   int use_follow;
  107.   {
  108. !     char *ng;
  109. !     ng = use_follow && news.ng_follow ? news.ng_follow : news.ng_groups;
  110. !     if (ng == NULL) return;
  111. !     
  112. !     fprintf(t, "Newsgroups: %s\n", ng);
  113.       ed_line++;
  114.   }
  115.   
  116. ***************
  117. *** 522,540 ****
  118.       if (command == K_BUG_REPORT) {
  119.           fprintf(t, "\n=== configuration ===\n");
  120.           append_file(relative(lib_directory, "conf"), t);
  121.           fprintf(t, "=== end ===\n");
  122.       }
  123.       }
  124.   
  125. -     /* empty line terminates header */
  126. -     fputc(NL, t);
  127. -     ed_line++;
  128.       prompt("\1WAIT\1");
  129.   
  130.       if (incl) {
  131.       register c, prevnl = 1;
  132.   
  133.       while ((c = getc(art)) != EOF) {
  134.           if (c == NL) {
  135.           putc(c, t);
  136. --- 526,545 ----
  137.       if (command == K_BUG_REPORT) {
  138.           fprintf(t, "\n=== configuration ===\n");
  139.           append_file(relative(lib_directory, "conf"), t);
  140. +         fprintf(t, "=== variable settings ===\n");
  141. +         print_variable_config(t, 0);
  142.           fprintf(t, "=== end ===\n");
  143.       }
  144.       }
  145.   
  146.       prompt("\1WAIT\1");
  147.   
  148.       if (incl) {
  149.       register c, prevnl = 1;
  150.   
  151. +     fputc(NL, t);
  152. +     ed_line++;
  153.       while ((c = getc(art)) != EOF) {
  154.           if (c == NL) {
  155.           putc(c, t);
  156. ***************
  157. *** 820,826 ****
  158.       if (!post_no_edit)
  159.       prompt("\1WAIT\1");
  160.   
  161. !     ed_line = 3;
  162.   #ifdef NNTP
  163.   #ifdef NNTP_MINI_INEWS_HEADER
  164.       mini_inews_header(t);
  165. --- 825,831 ----
  166.       if (!post_no_edit)
  167.       prompt("\1WAIT\1");
  168.   
  169. !     ed_line = 4;
  170.   #ifdef NNTP
  171.   #ifdef NNTP_MINI_INEWS_HEADER
  172.       mini_inews_header(t);
  173. *** ./LAST/aux.sh    Wed May 16 11:23:33 1990
  174. --- aux.sh    Thu May 17 15:14:18 1990
  175. ***************
  176. *** 166,171 ****
  177. --- 166,175 ----
  178.         { cat $WORK ; echo ; } >> $FNAME
  179.       fi
  180.       ;;
  181. +   ENV)
  182. +     set
  183. +     ;;
  184.     esac
  185.   done
  186.   
  187. *** ./LAST/conf/s-dynix3-0.h    Wed May 16 11:23:34 1990
  188. --- conf/s-dynix3-0.h    Thu May 17 01:05:27 1990
  189. ***************
  190. *** 7,9 ****
  191. --- 7,10 ----
  192.   
  193.   #undef HAVE_MULTIGROUP
  194.   FILE *popen ();
  195. + #define FAKE_INTERRUPT
  196. *** ./LAST/db.c    Wed May 16 11:22:35 1990
  197. --- db.c    Mon May 21 13:22:43 1990
  198. ***************
  199. *** 43,49 ****
  200.       current_digest_article = 0;
  201.   
  202.       if (gh == NULL) return 0;
  203. !     if (gh->master_flag & M_IGNORE_GROUP) return 0;
  204.       if (gh == current_group) return 1;
  205.   
  206.       current_group = gh;
  207. --- 43,49 ----
  208.       current_digest_article = 0;
  209.   
  210.       if (gh == NULL) return 0;
  211. ! /*    if (gh->master_flag & M_IGNORE_GROUP) return 0;    /* OBS */
  212.       if (gh == current_group) return 1;
  213.   
  214.       current_group = gh;
  215. ***************
  216. *** 51,57 ****
  217.       if (gh->group_flag & G_FOLDER) {
  218.       group_position = NULL;
  219.       group_file_name = NULL;
  220. !     strcpy(group_path_name, gh->group_name);
  221.       return 1;
  222.       }
  223.   
  224. --- 51,57 ----
  225.       if (gh->group_flag & G_FOLDER) {
  226.       group_position = NULL;
  227.       group_file_name = NULL;
  228. !     strcpy(group_path_name, gh->archive_file);
  229.       return 1;
  230.       }
  231.   
  232. ***************
  233. *** 565,571 ****
  234.       db_data_path(data_file, gh, d_or_x);
  235.   
  236.       if (mode == -1) {
  237. !     unlink(data_file);
  238.       f = NULL;
  239.       } else {
  240.       f = open_file(data_file, (mode & ~MUST_EXIST));
  241. --- 565,572 ----
  242.       db_data_path(data_file, gh, d_or_x);
  243.   
  244.       if (mode == -1) {
  245. !     if (unlink(data_file) < 0 && errno != ENOTDIR && errno != ENOENT)
  246. !         log_entry('E', "Cannot unlink %s (errno=%d)", data_file, errno);
  247.       f = NULL;
  248.       } else {
  249.       f = open_file(data_file, (mode & ~MUST_EXIST));
  250. *** ./LAST/doc/RELEASE_NOTES    Wed May 16 11:23:35 1990
  251. --- doc/RELEASE_NOTES    Mon May 21 13:38:16 1990
  252. ***************
  253. *** 154,160 ****
  254.   Prog:    nn
  255.   Title:    Remapping keys may interfere with Junk command.
  256.   From:    Robert.Stockton@ELROND.GANDALF.CS.CMU.EDU
  257.       Menu mode macros are invoked when the appropriate keystrokes are used
  258.       in the Junk command.  For example, when I rebound 'N' in menu mode to
  259.       a macro, it interfered with Junking of "Leave-Next" articles.
  260. --- 154,163 ----
  261.   Prog:    nn
  262.   Title:    Remapping keys may interfere with Junk command.
  263.   From:    Robert.Stockton@ELROND.GANDALF.CS.CMU.EDU
  264. ! Fixed:    Patch #3 [init.c keymap.c keymap.h group.c menu.c]
  265. !     (The fix involves a "shadow" keymap for the menu map keys bound to
  266. !     a macro.  The shadow binding is shown by :show map menu, ++Kim).
  267. !     
  268.       Menu mode macros are invoked when the appropriate keystrokes are used
  269.       in the Junk command.  For example, when I rebound 'N' in menu mode to
  270.       a macro, it interfered with Junking of "Leave-Next" articles.
  271. ***************
  272. *** 310,316 ****
  273.   
  274.   Prog:    nn
  275.   Title:    Interrupt char doesn't work (CBREAK/DYNIX)
  276. ! From:    Jaap Vermeulen <jaap@sequent.uucp>
  277.   
  278.       Interrupt (^C) does not work. ^G does work.
  279.       'stty' tells me I'm really using interrupt (^C).
  280. --- 313,320 ----
  281.   
  282.   Prog:    nn
  283.   Title:    Interrupt char doesn't work (CBREAK/DYNIX)
  284. ! From:    Jaap Vermeulen <jaap@sequent.uucp> + fix
  285. ! Fixed:    Patch #3 [term.c global.c s-dynix3-0.h s-template.h]
  286.   
  287.       Interrupt (^C) does not work. ^G does work.
  288.       'stty' tells me I'm really using interrupt (^C).
  289. ***************
  290. *** 445,450 ****
  291. --- 449,552 ----
  292.   From:    Bill Gaines <bill%iccdev@relay.EU.net> + fix
  293.   Fixed:    Patch #2 [Makefile]
  294.   
  295. + Prog:    nn
  296. + Title:    Cannot unsubscribe to last group in sequence
  297. + From:    Peter Andersen <datpete@daimi.dk>
  298. +     Chuq Von Rospach <chuq@Apple.COM>
  299. +     Jaap Vermeulen <jaap%sequent@relay.EU.net>
  300. + Fixed:    Patch #3 [newsrc.c]
  301. +     When keep_unsubscribed is false, unsubscribing to the last presented
  302. +     group has no effect (it is not saved in .newsrc.)
  303. + Prog:    nnusage
  304. + Title:    Manual not updated to reflect 6.4 behaviour and options
  305. + From:    dmr@csli.Stanford.EDU (Daniel M. Rosenberg)
  306. + Fixed:    Patch #3 [nnusage.1m]
  307. + Prog:    nn
  308. + Title:    Interactive :map # doesn't work
  309. + From:    Jaap Vermeulen <jaap%sequent@relay.EU.net>
  310. + Fixed:    Patch #3 [init.c]
  311. +     Interactive ':map #' is impossible.
  312. + Prog:    nn
  313. + Title:    Macros cannot be called by number using :macro N
  314. + From:    KFS
  315. + Fixed:    Patch #3 [init.c menu.c]
  316. + Prog:    nngrab
  317. + Title:    If keyword contain upper-case characters, nothing is found
  318. + From:    James A. Woods <jaw@riacs.edu>
  319. + Fixed:    Patch #3 [nngrab.sh nngrab.1 (new -c option)]
  320. +     Removing the -i option on egrep and folding the subjects database
  321. +     to lowercase (patch #2) breaks a command like "nngrab NeXT".
  322. + Prog:    nnmaster
  323. + Title:    From: ... (First Last - Division) is packed into "F L Division"
  324. + From:    olson%anchor.esd@sgi.com (Dave Olson)
  325. + Fixed:    Patch #3 [pack_name.c]
  326. + Prog:    nn
  327. + Title:    cursor isn't placed on the proper line in editor for :post cmd.
  328. + From:    arjen@mutad.uucp (Arjen Duursma) + fix
  329. + Fixed:    Patch #3 [answer.c]
  330. + Prog:    nn
  331. + Title:    A & B commands dump core in online manual and folders.
  332. + From:    Peter Radig <peter@radig.de>
  333. + Fixed:    Patch #3 [folder.c]
  334. + Prog:    nn
  335. + Title:    Return to menu with = in preview mode does not preserve attribute.
  336. + From:    Pekka Kyt|laakso <netmgr@csc.fi>
  337. + Fixed:    Patch #3 [menu.c]
  338. + Prog:    nn
  339. + Title:    Reply to a folder article w/o Newsgroups: header may dump core
  340. + From:    KFS
  341. + Fixed:    Patch #3 [answer.c]
  342. + Prog:    nn
  343. + Title:    default-save-file for folders is interpreted incorrectly
  344. + From:    Paul Petersen <petersen@uicsrd.csrd.uiuc.edu>
  345. + Fixed:    Patch #3 [save.c group.c variable.c nn.1 -- new folder-save-file]
  346. +     Say you have a folder of +alt.sources then the default save file is
  347. +     something like +/homes/petersen/News/alt.sources
  348. + Prog:    nnmaster
  349. + Title:    rmgrouped groups were not properly cleaned from the database
  350. + From:    chuq@Apple.COM
  351. + Fixed:    Patch #3 [master.c db.c group.c admin.c active.c]
  352. +     Groups which are removed from the active file are not properly
  353. +     removed from the database (actually another group would be removed!)
  354. + Prog:    nn
  355. + Title:    May dump core if saving to pipe and command fails.
  356. + From:    grady@scam.Berkeley.EDU (Steven Grady)
  357. +     nn just segmentation-faulted on me when I was doing ":unshar" on
  358. +     multiple articles.  The disk was full.
  359. + Prog:    nn
  360. + Title:    Unmark does not clear standout mode on HP terminals
  361. + From:    Bill Gaines <bill%iccdev@relay.EU.net>
  362. +     On HP terminals, if you mark an article, and then unmark it, the
  363. +     inverse video highlight does not go away.  You have to use "^L" to
  364. +     get a correct view of which articles are marked and which are not.
  365. + Prog:    nn
  366. + Title:    extended command help causes screen to be cleared after next command
  367. + From:    shields@nccnat.uucp (Paul Shields)
  368. +     In the command, ":? [space] pwd [return]" which prints the working
  369. +     directory correctly, but then repaints the screen immediately.
  370.   
  371.   New features since initial 6.4.0 release
  372.   ----------------------------------------
  373. ***************
  374. *** 463,465 ****
  375. --- 565,598 ----
  376.   Title:    updated to nntp release 1.5.8 (very minor changes!)
  377.   From:    KFS (with patches provided by Stan Barber)
  378.   Added:    Patch #2 [inews/*]
  379. + Prog:    nn
  380. + Title:    New marked-by-<command> variables
  381. + From:    KFS (inspired by a request from Jeff Sparkes)
  382. + Added:    Patch #3 [menu.c variable.c nn.1]
  383. +     The X, Z, and N can now be tuned regarding the amount of articles on
  384. +     the menu pages they will mark seen when executed.
  385. + Prog:    nn
  386. + Title:    :bug command now includes modified variables
  387. + From:    KFS (suggested by several users)
  388. + Added:    Patch #3 [variable.c answer.c]
  389. + Prog:    nn
  390. + Title:    New :print-variables command
  391. + From:    KFS
  392. + Added:    Patch #3 [variable.c init.c]
  393. + Prog:    nn
  394. + Title:    Arrow keys can now be redefined (e.g. map #up ^[ O A)
  395. + From:    KFS (on request from Jaap Vermeulen)
  396. + Fixed:    Patch #3 [init.c nn.1]
  397. +     I cannot define the up, down, right and left keys (in case they are
  398. +     not defined in my termcap entry).  Interactive ':map #' is impossible.
  399. + Prog:    nn
  400. + Title:    New folder-save-file variable for saving from folders.
  401. + From:    KFS (to fix problem with default-save-file)
  402. + Fixed:    Patch #3 [save.c group.c variable.c nn.1]
  403. *** ./LAST/folder.c    Thu Apr 26 14:28:28 1990
  404. --- folder.c    Fri May 18 23:22:24 1990
  405. ***************
  406. *** 252,260 ****
  407.       memory_marker        mem_marker;
  408.       group_header         fake_group;
  409.       int                cc_save;
  410.       extern time_stamp pack_date();
  411.   
  412. !     fake_group.group_name = path;
  413.       fake_group.group_flag = G_FOLDER | G_FAKED;
  414.       fake_group.master_flag = 0;
  415.       fake_group.save_file = NULL;
  416. --- 252,265 ----
  417.       memory_marker        mem_marker;
  418.       group_header         fake_group;
  419.       int                cc_save;
  420. +     char folder_name[FILENAME], folder_file[FILENAME];
  421.       extern time_stamp pack_date();
  422.   
  423. !     strcpy(folder_name, path);
  424. !     fake_group.group_name = folder_name;
  425. !     if (!expand_file_name(folder_file, folder_name, 1)) return ME_NO_REDRAW;
  426. !     fake_group.archive_file = path = folder_file;
  427. !     fake_group.next_group = fake_group.prev_group = NULL;
  428.       fake_group.group_flag = G_FOLDER | G_FAKED;
  429.       fake_group.master_flag = 0;
  430.       fake_group.save_file = NULL;
  431. ***************
  432. *** 332,340 ****
  433.       msg("Not a folder (no article header)");
  434.       menu_cmd = ME_NO_REDRAW;
  435.       } else {
  436. -     strcpy(buffer, path);
  437. -     fake_group.group_name = buffer;    /* save for later use */
  438.       if (n_articles > 1) {
  439.           clrdisp();
  440.           prompt_line = 2;
  441. --- 337,342 ----
  442. ***************
  443. *** 349,355 ****
  444.   
  445.       if (cancel_count) {
  446.           clrdisp();
  447. !         printf("Folder: %s\nFile:   %s\n\n", buffer, group_path_name);
  448.           if (cancel_count == n_articles)
  449.           printf("Cancel all articles and remove folder? ");
  450.           else
  451. --- 351,357 ----
  452.   
  453.       if (cancel_count) {
  454.           clrdisp();
  455. !         printf("Folder: %s\nFile:   %s\n\n", folder_name, folder_file);
  456.           if (cancel_count == n_articles)
  457.           printf("Cancel all articles and remove folder? ");
  458.           else
  459. *** ./LAST/global.c    Wed May 16 11:23:36 1990
  460. --- global.c    Thu May 17 00:41:24 1990
  461. ***************
  462. *** 76,81 ****
  463. --- 76,88 ----
  464.   export int s_pipe        = 0;    /* broken pipe */
  465.   export int s_redraw        = 0;    /* redraw signal (if job control) */
  466.   
  467. + #ifdef FAKE_INTERRUPT
  468. + #include <setjmp.h>
  469. + export jmp_buf fake_keyb_sig;
  470. + export int arm_fake_keyb_sig = 0;
  471. + #endif
  472.   sig_type catch_hangup(n)
  473.   {
  474.       signal(n, SIG_IGN);
  475. ***************
  476. *** 85,95 ****
  477.   
  478.   static sig_type catch_keyboard(n)
  479.   {
  480. -     s_keyboard++;
  481.   #ifdef RESET_SIGNAL_WHEN_CAUGHT
  482.       signal(n, catch_keyboard);
  483.   #endif
  484.   }
  485.   
  486.   static sig_type catch_pipe(n)
  487. --- 92,105 ----
  488.   
  489.   static sig_type catch_keyboard(n)
  490.   {
  491.   #ifdef RESET_SIGNAL_WHEN_CAUGHT
  492.       signal(n, catch_keyboard);
  493.   #endif
  494. + #ifdef FAKE_INTERRUPT
  495. +     if (arm_fake_keyb_sig)
  496. +     longjmp(fake_keyb_sig, 1);
  497. + #endif
  498. +     s_keyboard++;
  499.   }
  500.   
  501.   static sig_type catch_pipe(n)
  502. *** ./LAST/group.c    Wed May 16 11:23:37 1990
  503. --- group.c    Mon May 21 13:22:43 1990
  504. ***************
  505. *** 25,31 ****
  506.   import int  merged_menu, keep_unsubscribed, keep_unsub_long;
  507.   import int  killed_articles;
  508.   import int  seq_cross_filtering;
  509. ! import char *default_save_file;
  510.   
  511.   import char delayed_msg[];
  512.   import int32 db_read_counter;
  513. --- 25,31 ----
  514.   import int  merged_menu, keep_unsubscribed, keep_unsub_long;
  515.   import int  killed_articles;
  516.   import int  seq_cross_filtering;
  517. ! import char *default_save_file, *folder_save_file;
  518.   
  519.   import char delayed_msg[];
  520.   import int32 db_read_counter;
  521. ***************
  522. *** 191,197 ****
  523.   
  524.    reenter:
  525.       for (; gh; gh = gh->merge_with) {
  526. !     if (init_group(gh) <= 0) {
  527.           if (mg_head != NULL) continue;
  528.           menu_return( ME_NEXT );
  529.       }
  530. --- 191,197 ----
  531.   
  532.    reenter:
  533.       for (; gh; gh = gh->merge_with) {
  534. !     if ((gh->master_flag & M_IGNORE_GROUP) || init_group(gh) <= 0) {
  535.           if (mg_head != NULL) continue;
  536.           menu_return( ME_NEXT );
  537.       }
  538. ***************
  539. *** 361,367 ****
  540.       article_number first;
  541.       memory_marker mem_marker;
  542.       group_header *orig_group;
  543. !     int menu_cmd;
  544.       extern int menu(), file_completion();
  545.       extern article_header *get_menu_article();
  546.       extern int get_from_macro;
  547. --- 361,367 ----
  548.       article_number first;
  549.       memory_marker mem_marker;
  550.       group_header *orig_group;
  551. !     int menu_cmd, cmd_key;
  552.       extern int menu(), file_completion();
  553.       extern article_header *get_menu_article();
  554.       extern int get_from_macro;
  555. ***************
  556. *** 397,406 ****
  557.           
  558.           prompt("\1Enter\1 %s %s?  (ABGNPy) ", gh->group_name, buffer);
  559.           
  560. !         command = get_c();
  561. !         if (command & GETC_COMMAND) goto_return(ME_REDRAW);
  562. !         if (command == 'y') break;
  563. !         command = menu_key_map[command];
  564.       }
  565.   
  566.       switch (command) {
  567. --- 397,411 ----
  568.           
  569.           prompt("\1Enter\1 %s %s?  (ABGNPy) ", gh->group_name, buffer);
  570.           
  571. !         cmd_key = get_c();
  572. !         if (cmd_key & GETC_COMMAND) {
  573. !         command = cmd_key & ~GETC_COMMAND;
  574. !         if (command == K_REDRAW) goto_return(ME_REDRAW);
  575. !         } else {
  576. !         if (cmd_key == 'y') break;
  577. !         command = menu_key_map[cmd_key];
  578. !         if (command & K_MACRO) command = orig_menu_map[cmd_key];
  579. !         }
  580.       }
  581.   
  582.       switch (command) {
  583. ***************
  584. *** 480,490 ****
  585. --- 485,507 ----
  586.       if (current_group == NULL) goto_return(ME_NO_REDRAW);
  587.       if ((current_group->group_flag & G_FOLDER) == 0) {
  588.           if (!ah) {
  589. + #ifdef NNTP
  590. +         if (use_nntp) {
  591. +             msg("Can only use G%% in reading mode");
  592. +             goto_return(ME_NO_REDRAW);
  593. +         }
  594. + #endif
  595.           prompt("\1READ\1");
  596.           if ((ah = get_menu_article()) == NULL)
  597.               goto_return(ME_NO_REDRAW);
  598.           }
  599.           if ((ah->flag & A_DIGEST) == 0) {
  600. + #ifdef NNTP
  601. +         if (use_nntp) {
  602. +             answer = nntp_get_filename(ah->a_number, current_group);
  603. +             goto get_folder;
  604. +         }
  605. + #endif
  606.           *group_file_name = NUL;
  607.           sprintf(fbuffer, "%s%ld", group_path_name, ah->a_number);
  608.           answer = fbuffer;
  609. ***************
  610. *** 686,694 ****
  611.    get_folder:
  612.       m_endinput();
  613.       if (strcmp(answer, "+") == 0)
  614. !     answer = (gh && gh->save_file != NULL) ? gh->save_file : default_save_file;
  615. !     if (!expand_file_name(buffer, answer, 1)) goto_return (ME_NO_REDRAW);
  616. !     menu_cmd = folder_menu(buffer);
  617.       gh = NULL;
  618.       goto goto_exit;
  619.   
  620. --- 703,711 ----
  621.    get_folder:
  622.       m_endinput();
  623.       if (strcmp(answer, "+") == 0)
  624. !     answer = (gh && gh->save_file != NULL) ? gh->save_file : 
  625. !         (gh->group_flag & G_FOLDER) ? folder_save_file : default_save_file;
  626. !     menu_cmd = folder_menu(answer);
  627.       gh = NULL;
  628.       goto goto_exit;
  629.   
  630. *** ./LAST/init.c    Wed May 16 11:22:39 1990
  631. --- init.c    Fri May 18 11:51:11 1990
  632. ***************
  633. *** 245,250 ****
  634. --- 245,251 ----
  635.       "local",            5,    3,
  636.       "man",            3,    0,
  637.       "map",            3,    -1,
  638. +     "map #",            5,    -2,
  639.       "map both",            8,    4,
  640.       "map key",            7,    0,
  641.       "map menu",            8,    4,
  642. ***************
  643. *** 252,258 ****
  644.       "mkdir",            5,    1,
  645.       "patch",            5,    0, /* QUICK HACK */
  646.       "post",            4,    0, /* QUICK HACK */
  647. !     "print",            5,    0, /* QUICK HACK */
  648.       "pwd",            3,    0,
  649.       "rmail",            5,    0,
  650.       "set",            3,    3,
  651. --- 253,260 ----
  652.       "mkdir",            5,    1,
  653.       "patch",            5,    0, /* QUICK HACK */
  654.       "post",            4,    0, /* QUICK HACK */
  655. !     "print",            5,    -3, /* QUICK HACK */
  656. !     "print-variables",        15,    0,
  657.       "pwd",            3,    0,
  658.       "rmail",            5,    0,
  659.       "set",            3,    3,
  660. ***************
  661. *** 315,321 ****
  662.       other_compl = NULL;
  663.   
  664.       for (; alt->alt_name; alt++) {
  665. !         if (len <= alt->alt_len || head[alt->alt_len] != SP) continue;
  666.           index = strncmp(alt->alt_name, head, alt->alt_len);
  667.           if (index < 0) continue;
  668.           if (index > 0) break;
  669. --- 317,328 ----
  670.       other_compl = NULL;
  671.   
  672.       for (; alt->alt_name; alt++) {
  673. !         if (len <= alt->alt_len) continue;
  674. !         if (head[alt->alt_len] != SP) {
  675. !         if (alt->alt_type != -2) continue;
  676. !         if (strncmp(alt->alt_name, head, alt->alt_len)) continue;
  677. !         return -1;
  678. !         }
  679.           index = strncmp(alt->alt_name, head, alt->alt_len);
  680.           if (index < 0) continue;
  681.           if (index > 0) break;
  682. ***************
  683. *** 402,407 ****
  684. --- 409,419 ----
  685.           if (list_completion(p) == 0) break;
  686.           temp = help_alt->alt_len;
  687.   
  688. +         if (help_alt->alt_type == -3) {
  689. +         help_alt++;
  690. +         continue;
  691. +         }
  692. +     
  693.           do help_alt++;
  694.           while ((q = help_alt->alt_name) && help_alt->alt_len > temp &&
  695.              strncmp(p, q, temp) == 0);
  696. ***************
  697. *** 420,435 ****
  698.       if (index > 0) break;
  699.   
  700.       p = alt->alt_name;
  701. !     sprintf(tail, "%s ", p + len);
  702.       temp = alt->alt_len;
  703.   
  704.       do alt++;
  705. !     while ((q = alt->alt_name) && alt->alt_len > temp &&
  706.              strncmp(p, q, temp) == 0);
  707.   
  708.       return 1;
  709.       }
  710. !     return 0;
  711.   }
  712.   
  713.   static print_debug_info()
  714. --- 432,459 ----
  715.       if (index > 0) break;
  716.   
  717.       p = alt->alt_name;
  718. !     sprintf(tail, "%s%s", p + len, alt->alt_type <= -2 ? "" : " ");
  719.       temp = alt->alt_len;
  720.   
  721. +     if (alt->alt_type == -3) {
  722. +         alt++;
  723. +         return 1;
  724. +     }
  725. +     
  726.       do alt++;
  727. !     while ((q = alt->alt_name) && alt->alt_len > temp && 
  728.              strncmp(p, q, temp) == 0);
  729.   
  730.       return 1;
  731.       }
  732. !     cmd_completion(head, len);
  733. !     if (temp = cmd_completion((char *)NULL, 0)) {
  734. !     other_compl = cmd_completion;
  735. !     tail = NULL;
  736. !     }
  737. !     return temp;
  738.   }
  739.   
  740.   static print_debug_info()
  741. ***************
  742. *** 574,579 ****
  743. --- 598,604 ----
  744.   FILE *initf;
  745.   {
  746.       int code, map_menu, map_show, must_redraw = 0;
  747. +     key_type bind_to;
  748.   
  749.       SWITCH( argv(1) ) {
  750.   
  751. ***************
  752. *** 587,600 ****
  753.           key_type multi_buffer[16], *mb;
  754.           int i;
  755.   
  756. !         if (!isdigit(argv(1)[1])) break;
  757.   
  758.           for (i = 2, mb = multi_buffer; argv(i); i++)
  759.           *mb++ = parse_key(argv(i));
  760.           *mb = NUL;
  761.   
  762. !         enter_multi_key(K_function(argv(1)[1] - '0'),
  763. !                 (key_type *)copy_str((char *)multi_buffer));
  764.   
  765.           goto out;
  766.       }
  767. --- 612,630 ----
  768.           key_type multi_buffer[16], *mb;
  769.           int i;
  770.   
  771. !         if (argv(1)[1] == NUL) break;
  772. !         if (isdigit(argv(1)[1])) 
  773. !         bind_to = K_function(argv(1)[1] - '0');
  774. !         else {
  775. !         bind_to = parse_key(argv(1) + 1);
  776. !         if (bind_to <= 0x80) break; /* not pretty! */
  777. !         }
  778.   
  779.           for (i = 2, mb = multi_buffer; argv(i); i++)
  780.           *mb++ = parse_key(argv(i));
  781.           *mb = NUL;
  782.   
  783. !         enter_multi_key(bind_to, (key_type *)copy_str((char *)multi_buffer));
  784.   
  785.           goto out;
  786.       }
  787. ***************
  788. *** 638,644 ****
  789.               goto mac_err;
  790.   
  791.           if (code != K_INVALID) {
  792. !         menu_key_map[parse_key(argv(2))] = code;
  793.           if (!map_show) goto out;
  794.           }
  795.       }
  796. --- 668,677 ----
  797.               goto mac_err;
  798.   
  799.           if (code != K_INVALID) {
  800. !         bind_to = parse_key(argv(2));
  801. !         if (code & K_MACRO && orig_menu_map[bind_to] == 0)
  802. !             orig_menu_map[bind_to] = menu_key_map[bind_to];
  803. !         menu_key_map[bind_to] = code;
  804.           if (!map_show) goto out;
  805.           }
  806.       }
  807. ***************
  808. *** 906,913 ****
  809.   
  810.           alt_cmd_key = lookup_command(sw_string,
  811.                    in_menu_mode ? K_ONLY_MENU : K_ONLY_MORE);
  812. !         if (alt_cmd_key != K_INVALID && alt_cmd_key != K_HELP)
  813.           return AC_KEYCMD;
  814.       }
  815.   
  816.       CASE( "q" ) {
  817. --- 939,951 ----
  818.   
  819.           alt_cmd_key = lookup_command(sw_string,
  820.                    in_menu_mode ? K_ONLY_MENU : K_ONLY_MORE);
  821. !         if (alt_cmd_key != K_INVALID && alt_cmd_key != K_HELP) {
  822. !         if (alt_cmd_key == K_MACRO) {
  823. !             if (ARGTAIL == NULL) break;
  824. !             alt_cmd_key |= atoi(ARGTAIL);
  825. !         }
  826.           return AC_KEYCMD;
  827. +         }
  828.       }
  829.   
  830.       CASE( "q" ) {
  831. ***************
  832. *** 1033,1038 ****
  833. --- 1071,1087 ----
  834.           return AC_REDRAW;
  835.       }
  836.   
  837. +     CASE( "print-variables" ) {
  838. +         import char printer[];
  839. +         FILE *p;
  840. +         if (p = popen(ARGTAIL ? ARGTAIL : printer, "w")) {
  841. +         print_variable_config(p, 1);
  842. +         pclose(p);
  843. +         msg("Variables printed");
  844. +         }
  845. +         break;
  846. +     }
  847. +     
  848.       CASE( "pwd" ) {
  849.           FILE *p = popen("exec pwd", "r");
  850.           char dir[FILENAME];
  851. *** ./LAST/keymap.c    Fri Apr 27 21:30:58 1990
  852. --- keymap.c    Thu May 17 11:19:11 1990
  853. ***************
  854. *** 410,415 ****
  855. --- 410,416 ----
  856.   /* #9  */    K_UNBOUND
  857.   };
  858.   
  859. + export int orig_menu_map[KEY_MAP_SIZE];    /* initially empty */
  860.   
  861.   
  862.   static struct command_name_map {
  863. ***************
  864. *** 797,802 ****
  865. --- 798,805 ----
  866.       if (map[c] & K_MACRO) {
  867.           if (pg_next() < 0) goto out;
  868.           printf("macro %d: %s", (map[c] & ~K_MACRO), key_name(c));
  869. +         if (map == menu_key_map && orig_menu_map[c] != K_UNBOUND) 
  870. +         printf(" (%s)", command_name(orig_menu_map[c]));
  871.       }
  872.   
  873.    out:
  874. *** ./LAST/keymap.h    Thu Apr 26 21:10:15 1990
  875. --- keymap.h    Thu May 17 11:19:12 1990
  876. ***************
  877. *** 123,128 ****
  878. --- 123,129 ----
  879.   
  880.   extern int menu_key_map[];
  881.   extern int more_key_map[];
  882. + extern int orig_menu_map[];
  883.   
  884.   extern key_type global_key_map[];
  885.   
  886. *** ./LAST/man/nn.1.A    Wed May 16 11:23:42 1990
  887. --- man/nn.1.A    Mon May 21 17:18:31 1990
  888. ***************
  889. *** 598,607 ****
  890.   articles have been read, return to selection mode in the
  891.   .I current
  892.   group.  It will mark \fIselected\fP articles \fIread\fP as they are
  893. ! read, but \fIunread\fP articles are not changed.
  894.   .TP
  895.   \&\fBX\fP    {\fBread-skip\fP}
  896. ! Mark all \fIunread\fP articles \fIseen\fP on all menu pages, and enter
  897.   reading mode \fIimmediately\fP with the currently selected articles.
  898.   As the selected articles are read, they are marked \fIread\fP.  When
  899.   all selected articles have been read, \fInn\fP will enter selection
  900. --- 598,609 ----
  901.   articles have been read, return to selection mode in the
  902.   .I current
  903.   group.  It will mark \fIselected\fP articles \fIread\fP as they are
  904. ! read, but \fIunread\fP articles are not normally changed (can be
  905. ! controlled with the variable \fBmarked-by-read-return\fP.)
  906.   .TP
  907.   \&\fBX\fP    {\fBread-skip\fP}
  908. ! Mark all \fIunmarked\fP articles \fIseen\fP on all menu pages (or the
  909. ! pages defined by the \fBmarked-by-read-skip\fP variable), and enter
  910.   reading mode \fIimmediately\fP with the currently selected articles.
  911.   As the selected articles are read, they are marked \fIread\fP.  When
  912.   all selected articles have been read, \fInn\fP will enter selection
  913. ***************
  914. *** 614,623 ****
  915.   for later, you can use the following commands which will only mark
  916.   \fIseen\fP and \fIread\fP articles as read.  Currently selected
  917.   articles will still be selected the next time you enter the group.
  918. ! None of these commands will change any attributes themselves.
  919.   .TP
  920.   \&\fBN\fP    {\fBnext-group\fP}
  921. ! Go forward to the next group in the presentation sequence.
  922.   .TP
  923.   \&\fBP\fP    {\fBprevious\fP}
  924.   Go back to the previous group.  This command will enter selection mode
  925. --- 616,627 ----
  926.   for later, you can use the following commands which will only mark
  927.   \fIseen\fP and \fIread\fP articles as read.  Currently selected
  928.   articles will still be selected the next time you enter the group.
  929. ! None of these commands will change any attributes themselves (by default).
  930.   .TP
  931.   \&\fBN\fP    {\fBnext-group\fP}
  932. ! Go forward to the next group in the presentation sequence.  If the
  933. ! variable \fBmarked-by-next-group\fP is set articles on the menu can
  934. ! optionally be marked \fIseen\fP
  935.   .TP
  936.   \&\fBP\fP    {\fBprevious\fP}
  937.   Go back to the previous group.  This command will enter selection mode
  938. ***************
  939. *** 653,661 ****
  940.   command.
  941.   .LP
  942.   \fBRelated variables\fP:
  943. ! auto-preview-mode, auto-select-subject, case-fold-search,
  944. ! confirm-auto-quit, confirm-entry,
  945. ! auto-junk-seen, confirm-junk-seen, retain-seen-status, select-on-sender.
  946.   .SH THE JUNK-ARTICLES AND LEAVE-NEXT COMMANDS
  947.   The \fBJ\fP {\fBjunk-articles\fP} command is a very flexible command
  948.   which can perform all sorts of attribute changes, either on individual
  949. --- 657,666 ----
  950.   command.
  951.   .LP
  952.   \fBRelated variables\fP:
  953. ! auto-junk-seen, auto-preview-mode, auto-select-subject, case-fold-search,
  954. ! confirm-auto-quit, confirm-entry, confirm-junk-seen,
  955. ! marked-by-next-group, marked-by-read-return, marked-by-read-skip,
  956. ! retain-seen-status, select-on-sender.
  957.   .SH THE JUNK-ARTICLES AND LEAVE-NEXT COMMANDS
  958.   The \fBJ\fP {\fBjunk-articles\fP} command is a very flexible command
  959.   which can perform all sorts of attribute changes, either on individual
  960. ***************
  961. *** 1104,1110 ****
  962.   .LP
  963.   \fBRelated variables\fP:
  964.   confirm-append, confirm-create, decode-header-file,
  965. ! decode-skip-prefix, default-save-file,
  966.   edit-patch-command, edit-print-command, edit-unshar-command, folder,
  967.   mail-format, mmdf-format, patch-command, printer, quick-save,
  968.   save-counter, save-counter-offset, save-report,
  969. --- 1109,1115 ----
  970.   .LP
  971.   \fBRelated variables\fP:
  972.   confirm-append, confirm-create, decode-header-file,
  973. ! decode-skip-prefix, default-save-file, folder-save-file,
  974.   edit-patch-command, edit-print-command, edit-unshar-command, folder,
  975.   mail-format, mmdf-format, patch-command, printer, quick-save,
  976.   save-counter, save-counter-offset, save-report,
  977. *** ./LAST/man/nn.1.B    Wed May 16 11:23:44 1990
  978. --- man/nn.1.B    Mon May 21 17:18:31 1990
  979. ***************
  980. *** 18,24 ****
  981.   \fB+\fP
  982.   A single plus is replaced by the expansion of the file name contained in the
  983.   .B default-save-file
  984. ! variable.
  985.   .TP
  986.   \fB~/\fP\fIfile\fP
  987.   The
  988. --- 18,24 ----
  989.   \fB+\fP
  990.   A single plus is replaced by the expansion of the file name contained in the
  991.   .B default-save-file
  992. ! variable (or by \fBfolder-save-file\fP when saving from a folder).
  993.   .TP
  994.   \fB~/\fP\fIfile\fP
  995.   The
  996. ***************
  997. *** 85,91 ****
  998.   next in part3.shar, and so on).
  999.   .LP
  1000.   \fBRelated variables\fP:
  1001. ! default-save-file, folder, save-counter, save-counter-offset.
  1002.   .SH FILE AND GROUP NAME COMPLETION
  1003.   When entering a file name or a news group name, a simple
  1004.   .B completion
  1005. --- 85,91 ----
  1006.   next in part3.shar, and so on).
  1007.   .LP
  1008.   \fBRelated variables\fP:
  1009. ! default-save-file, folder, folder-save-file, save-counter, save-counter-offset.
  1010.   .SH FILE AND GROUP NAME COMPLETION
  1011.   When entering a file name or a news group name, a simple
  1012.   .B completion
  1013. ***************
  1014. *** 423,429 ****
  1015.   .fi
  1016.   .LP
  1017.   \fBRelated variables\fP:
  1018. ! case-fold-search, default-save-file
  1019.   .SH AUTOMATIC KILL AND SELECTION
  1020.   When there is a subject or an author which you are either very
  1021.   interested in, or find completely uninteresting, you can easily
  1022. --- 423,429 ----
  1023.   .fi
  1024.   .LP
  1025.   \fBRelated variables\fP:
  1026. ! case-fold-search, default-save-file, folder-save-file
  1027.   .SH AUTOMATIC KILL AND SELECTION
  1028.   When there is a subject or an author which you are either very
  1029.   interested in, or find completely uninteresting, you can easily
  1030. *** ./LAST/man/nn.1.C    Wed May 16 11:23:46 1990
  1031. --- man/nn.1.C    Mon May 21 17:18:31 1990
  1032. ***************
  1033. *** 342,350 ****
  1034.   the subject for the specified period.
  1035.   .TP
  1036.   \fBdefault-save-file\fP \fIfile\fP    (string, default +$F)
  1037. ! The default save file used in quick save mode.  It can also be
  1038. ! specified using the abbreviation "+" as the file name in normal save
  1039. ! mode.
  1040.   .TP
  1041.   \fBdelay-redraw\fP        (boolean, default false)
  1042.   Normally, \fInn\fP will redraw the screen after extended
  1043. --- 342,352 ----
  1044.   the subject for the specified period.
  1045.   .TP
  1046.   \fBdefault-save-file\fP \fIfile\fP    (string, default +$F)
  1047. ! The default save file used when saving articles in news groups where
  1048. ! no save file has been specified in the init file (either in a
  1049. ! \fBsave-files\fP section or in the presentation sequence).
  1050. ! It can also be specified using the abbreviation "+" as the file name
  1051. ! when prompted for a file name even in groups with their own save file.
  1052.   .TP
  1053.   \fBdelay-redraw\fP        (boolean, default false)
  1054.   Normally, \fInn\fP will redraw the screen after extended
  1055. ***************
  1056. *** 425,430 ****
  1057. --- 427,435 ----
  1058.   .I init
  1059.   file.
  1060.   .TP
  1061. + \fBfolder-save-file\fP \fIfile\fP    (string, default not set)
  1062. + The default save file used when saving articles \fIfrom\fP a folder.
  1063. + .TP
  1064.   \fBfsort\fP        (boolean, default true)
  1065.   When set, folders are sorted alphabetically according to the subject
  1066.   (and age).
  1067. ***************
  1068. *** 523,529 ****
  1069.   sent from \fInn\fP using the \fBreply\fP and \fBmail\fP commands.  For
  1070.   example:
  1071.   .br
  1072. !    set mail-header Reply-To: storm@texas.dk
  1073.   .br
  1074.   .TP
  1075.   \fBmail-record\fP \fIfile\fP    (string, default not set)
  1076. --- 528,534 ----
  1077.   sent from \fInn\fP using the \fBreply\fP and \fBmail\fP commands.  For
  1078.   example:
  1079.   .br
  1080. !    set mail-header Reply-To: storm@texas.dk;Organization: TI - DK
  1081.   .br
  1082.   .TP
  1083.   \fBmail-record\fP \fIfile\fP    (string, default not set)
  1084. ***************
  1085. *** 549,554 ****
  1086. --- 554,582 ----
  1087.   program.  Otherwise, the file containing the message will be given as
  1088.   the first (and only) argument to the \fBmailer\fP command.
  1089.   .TP
  1090. + \fBmarked-by-next-group\fP \fIN\fP    (integer, default 0)
  1091. + Specifies the amount of (unmarked) articles on the menu marked
  1092. + \fIseen\fP by the \fBN\fP {\fBnext-group\fP} command in selection
  1093. + mode.  See \fBmarked-by-read-skip\fP for possible values of \fIN\fP.
  1094. + .TP
  1095. + \fBmarked-by-read-return\fP \fIN\fP    (integer, default 0)
  1096. + Specifies the amount of (unmarked) articles on the menu marked
  1097. + \fIseen\fP by the \fBZ\fP {\fBread-return\fP} command in selection
  1098. + mode.  See \fBmarked-by-read-skip\fP for possible values of \fIN\fP.
  1099. + .TP
  1100. + \fBmarked-by-read-skip\fP \fIN\fP    (integer, default 4)
  1101. + Specifies the amount of (unmarked) articles on the menu marked
  1102. + \fIseen\fP by the \fBX\fP {\fBread-skip\fP} command in selection mode.
  1103. + The following values of \fIN\fP are recognized:
  1104. + .br
  1105. + .nf
  1106. +     0:  No articles are marked seen
  1107. +     1:  Current page is marked seen
  1108. +     2:  Previous pages are marked seen
  1109. +     3:  Previous and current pages are marked seen
  1110. +     4:  All pages are marked seen
  1111. + .fi
  1112. + .TP
  1113.   \fBmark-overlap\fP    (boolean, default false)
  1114.   When set, \fInn\fP will draw a line (using the underline capabilities
  1115.   of the terminal if possible) to indicate the end of the overlap (see the
  1116. ***************
  1117. *** 602,608 ****
  1118.   The \fIheaders\fP string specifies one or more extra header lines
  1119.   (separated by semi-colons `;') which are added to the header of
  1120.   articles posted from \fInn\fP using the \fBfollow\fP and \fBpost\fP
  1121. ! commands.
  1122.   .TP
  1123.   \fBnews-record\fP \fIfile\fP    (string, default not set)
  1124.   Save file for follow-ups and postings.  Same rules and format as the
  1125. --- 630,636 ----
  1126.   The \fIheaders\fP string specifies one or more extra header lines
  1127.   (separated by semi-colons `;') which are added to the header of
  1128.   articles posted from \fInn\fP using the \fBfollow\fP and \fBpost\fP
  1129. ! commands.  See \fBmail-header\fP for an example.
  1130.   .TP
  1131.   \fBnews-record\fP \fIfile\fP    (string, default not set)
  1132.   Save file for follow-ups and postings.  Same rules and format as the
  1133. ***************
  1134. *** 919,925 ****
  1135.   \fBsuggest-default-save\fP    (boolean, default true)
  1136.   When set, \fInn\fP will present the \fBdefault-save-file\fP when
  1137.   prompting for a save file name in a group without a specific save
  1138. ! file.  When not set, no file name is presented, and to use the default
  1139.   save file, a single + must be specified.
  1140.   .TP
  1141.   \fBtidy-newsrc\fP        (boolean, default false)
  1142. --- 947,954 ----
  1143.   \fBsuggest-default-save\fP    (boolean, default true)
  1144.   When set, \fInn\fP will present the \fBdefault-save-file\fP when
  1145.   prompting for a save file name in a group without a specific save
  1146. ! file, or \fBfolder-save-file\fP when saving from a folder.  When not
  1147. ! set, no file name is presented, and to use the default
  1148.   save file, a single + must be specified.
  1149.   .TP
  1150.   \fBtidy-newsrc\fP        (boolean, default false)
  1151. *** ./LAST/man/nn.1.D    Wed May 16 11:23:47 1990
  1152. --- man/nn.1.D    Mon May 21 17:18:31 1990
  1153. ***************
  1154. *** 423,429 ****
  1155.   .BR #9
  1156.   for the user-defined keys.
  1157.   .sp 0.5v
  1158. ! Multikey #\fIi\fP is defined using the following command:
  1159.   .sp 0.5v
  1160.       \fBmap #\fP\fIi\fP \fIkey-sequence\fP
  1161.   .sp 0.5v
  1162. --- 423,430 ----
  1163.   .BR #9
  1164.   for the user-defined keys.
  1165.   .sp 0.5v
  1166. ! Multikey #\fIi\fP (where \fIi\fP is a digit or an arrow key name) is
  1167. ! defined using the following command:
  1168.   .sp 0.5v
  1169.       \fBmap #\fP\fIi\fP \fIkey-sequence\fP
  1170.   .sp 0.5v
  1171. *** ./LAST/man/nngrab.1    Wed May 16 11:23:50 1990
  1172. --- man/nngrab.1    Fri May 18 20:22:23 1990
  1173. ***************
  1174. *** 3,10 ****
  1175.   .SH NAME
  1176.   nngrab \- news retrieval by keyword (nn)
  1177.   .SH SYNOPSIS
  1178. ! .B nngrab
  1179. ! .I keyword
  1180.   .SH DESCRIPTION
  1181.   .I nngrab
  1182.   invokes \fInn\fP
  1183. --- 3,9 ----
  1184.   .SH NAME
  1185.   nngrab \- news retrieval by keyword (nn)
  1186.   .SH SYNOPSIS
  1187. ! \fBnngrab\fP [ \-\fBc\fP ] \fIkeyword\fP
  1188.   .SH DESCRIPTION
  1189.   .I nngrab
  1190.   invokes \fInn\fP
  1191. ***************
  1192. *** 20,26 ****
  1193.   .sp 0.5v
  1194.   will retrieve items concerning Nikola Tesla.
  1195.   .LP
  1196. ! Keyword case is ignored, and the \fIkeyword\fP can be a regular
  1197.   expressions (escaped to avoid conflicts with the shell).  For example,
  1198.   .sp 0.5v
  1199.       nngrab "n.*tesla"
  1200. --- 19,26 ----
  1201.   .sp 0.5v
  1202.   will retrieve items concerning Nikola Tesla.
  1203.   .LP
  1204. ! Keyword case is ignored unless \-\fBc\fP is specified, and the
  1205. ! \fIkeyword\fP can be a regular
  1206.   expressions (escaped to avoid conflicts with the shell).  For example,
  1207.   .sp 0.5v
  1208.       nngrab "n.*tesla"
  1209. *** ./LAST/man/nnusage.1m    Sat Mar 31 23:12:58 1990
  1210. --- man/nnusage.1m    Fri May 18 23:22:23 1990
  1211. ***************
  1212. *** 5,21 ****
  1213.   nnusage \- display \fInn\fP usage statistics
  1214.   .SH SYNOPSIS
  1215.   .B nnusage
  1216. ! [ -t ]
  1217.   .SH DESCRIPTION
  1218.   .B nnusage
  1219.   will extract the usage entries from the log file and calculate the
  1220. ! total usage time for each \fInn\fP user.
  1221.   .LP
  1222. ! Without options, the output will be sorted according to user names.
  1223.   .LP
  1224. - With the \-t option, \fInnusage\fP will list the users ordered after
  1225. - the total usage time.
  1226. - .LP
  1227.   Since it is possible to
  1228.   suspend
  1229.   \fInn\fP, or leave the terminal while \fInn\fP is active, \fInn\fP
  1230. --- 5,21 ----
  1231.   nnusage \- display \fInn\fP usage statistics
  1232.   .SH SYNOPSIS
  1233.   .B nnusage
  1234. ! [ \-\fBat\fP ]
  1235.   .SH DESCRIPTION
  1236.   .B nnusage
  1237.   will extract the usage entries from the log file and calculate the
  1238. ! total usage time for the current user, or for all \fInn\fP users if
  1239. ! \-\fBa\fP is specified.
  1240.   .LP
  1241. ! When \-\fBt\fP is used with the \-\fBa\fP option, \fInnusage\fP will
  1242. ! list the users ordered after the total usage time.  Otherwise, the
  1243. ! output will be sorted according to user names.
  1244.   .LP
  1245.   Since it is possible to
  1246.   suspend
  1247.   \fInn\fP, or leave the terminal while \fInn\fP is active, \fInn\fP
  1248. ***************
  1249. *** 30,37 ****
  1250.   .SH SEE ALSO
  1251.   nn(1), nncheck(1), nngoback(1), nngrep(1), nntidy(1)
  1252.   .br
  1253. ! nnadmin(1M), nnquery(1M), nnmaster(8)
  1254.   .SH NOTES
  1255.   The \fInn\fP package must have been compiled with the STATISTICS
  1256.   option turned on to produce the usage entries in the log file.
  1257.   .LP
  1258. --- 30,40 ----
  1259.   .SH SEE ALSO
  1260.   nn(1), nncheck(1), nngoback(1), nngrep(1), nntidy(1)
  1261.   .br
  1262. ! nnacct(1m), nnadmin(1M), nnquery(1M), nnmaster(8)
  1263.   .SH NOTES
  1264. + If \fInn\fP is compiled with ACCOUNTING turned on, then calls to
  1265. + \fInnusage\fP are converted into equivalent calls to \fInnacct\fP.
  1266. + .LP
  1267.   The \fInn\fP package must have been compiled with the STATISTICS
  1268.   option turned on to produce the usage entries in the log file.
  1269.   .LP
  1270. *** ./LAST/master.c    Wed May 16 11:22:45 1990
  1271. --- master.c    Mon May 21 13:22:43 1990
  1272. ***************
  1273. *** 171,183 ****
  1274.       gh->first_db_article = 0;
  1275.       gh->last_db_article = 0;
  1276.   
  1277. !     if (gh->data_write_offset > (off_t)0) {
  1278. !     gh->data_write_offset = (off_t)0;
  1279.       (void)open_data_file(gh, 'd', -1);
  1280. -     }
  1281. -     
  1282. -     if (gh->index_write_offset) {
  1283. -     gh->index_write_offset = (off_t)0;
  1284.       (void)open_data_file(gh, 'x', -1);
  1285.       }
  1286.       
  1287. --- 171,181 ----
  1288.       gh->first_db_article = 0;
  1289.       gh->last_db_article = 0;
  1290.   
  1291. !     gh->data_write_offset = (off_t)0;
  1292. !     gh->index_write_offset = (off_t)0;
  1293. !     if (init_group(gh)) {
  1294.       (void)open_data_file(gh, 'd', -1);
  1295.       (void)open_data_file(gh, 'x', -1);
  1296.       }
  1297.       
  1298. ***************
  1299. *** 438,445 ****
  1300.       next_g->next_group = gh;
  1301.       next_g = gh;
  1302.       gh->next_group = NULL;
  1303. -     init_group(gh);    /* for clean_group() */
  1304.   
  1305.       /* moderation flag will be set by first visit_active_file call */
  1306.   
  1307. --- 436,441 ----
  1308. *** ./LAST/menu.c    Wed May 16 11:23:53 1990
  1309. --- menu.c    Fri May 18 22:26:07 1990
  1310. ***************
  1311. *** 24,29 ****
  1312. --- 24,32 ----
  1313.   export int  collapse_subject = 25; /* collapse long subjects at position */
  1314.   export int  conf_group_entry = 0; /* ask whether group should be entered */
  1315.   export int  conf_entry_limit = 0; /* ask only if more than .. unread */
  1316. + export int  mark_read_skip = 4; /* effect of X command */
  1317. + export int  mark_read_return = 0; /* effect of Z command */
  1318. + export int  mark_next_group = 0; /* effect of N command */
  1319.   
  1320.   export int  auto_preview_mode = 0; /* preview rather than select */
  1321.   export int  preview_continuation = 12; /* what to do after preview */
  1322. ***************
  1323. *** 452,458 ****
  1324.   static int article_id;
  1325.   static int cur_key;
  1326.   
  1327. ! static int get_k_cmd()
  1328.   {
  1329.       extern int any_message;
  1330.       register int c, map;
  1331. --- 455,461 ----
  1332.   static int article_id;
  1333.   static int cur_key;
  1334.   
  1335. ! static int get_k_cmd_1()
  1336.   {
  1337.       extern int any_message;
  1338.       register int c, map;
  1339. ***************
  1340. *** 472,482 ****
  1341.       }
  1342.       if (s_hangup) map = K_QUIT;
  1343.   
  1344. -     if (map & K_MACRO) {
  1345. -     m_invoke(map & ~K_MACRO);
  1346. -     goto loop;
  1347. -     }
  1348.       if (map & K_ARTICLE_ID) {
  1349.       article_id = map & ~K_ARTICLE_ID;
  1350.       map = K_ARTICLE_ID;
  1351. --- 475,480 ----
  1352. ***************
  1353. *** 491,496 ****
  1354. --- 489,504 ----
  1355.       return map;
  1356.   }
  1357.   
  1358. + static int get_k_cmd()
  1359. + {
  1360. +     register int map;
  1361. +     map = get_k_cmd_1();
  1362. +     if (map & K_MACRO)
  1363. +     map = orig_menu_map[cur_key];
  1364. +     return map;
  1365. + }
  1366.   
  1367.   char *pct(start, end, first, last)
  1368.   long start, end, first, last;
  1369. ***************
  1370. *** 592,598 ****
  1371.       int            doing_unshar, did_unshar, junk_prompt;
  1372.       char         *fname, *savemode, *init_save();
  1373.       int         maxa;    /* max no of articles per menu page */
  1374. !     int         o_firsta, o_mode;    /* for recursive calls */
  1375.       static        menu_level = 0;
  1376.       char        purpose[80], pr_fmt[60];
  1377.       extern int         enable_stop, file_completion();
  1378. --- 600,607 ----
  1379.       int            doing_unshar, did_unshar, junk_prompt;
  1380.       char         *fname, *savemode, *init_save();
  1381.       int         maxa;    /* max no of articles per menu page */
  1382. !     article_number    o_firsta, temp1, temp2;
  1383. !     int            o_mode;    /* for recursive calls */
  1384.       static        menu_level = 0;
  1385.       char        purpose[80], pr_fmt[60];
  1386.       extern int         enable_stop, file_completion();
  1387. ***************
  1388. *** 752,760 ****
  1389.        }
  1390.   
  1391.        last_k_cmd = cur_k_cmd;
  1392. -      k_cmd = get_k_cmd();
  1393.   
  1394.     alt_key:
  1395.   
  1396.        switch (cur_k_cmd = k_cmd) {
  1397.   
  1398. --- 761,775 ----
  1399.        }
  1400.   
  1401.        last_k_cmd = cur_k_cmd;
  1402.   
  1403. +   get_next_k_cmd:
  1404. +      k_cmd = get_k_cmd_1();
  1405.     alt_key:
  1406. +     if (k_cmd & K_MACRO) {
  1407. +     m_invoke(k_cmd & ~K_MACRO);
  1408. +     goto get_next_k_cmd;
  1409. +     }
  1410.   
  1411.        switch (cur_k_cmd = k_cmd) {
  1412.   
  1413. ***************
  1414. *** 1022,1035 ****
  1415.        if (nexta < n_articles) goto nextmenu;
  1416.        break;
  1417.   
  1418. -       case K_READ_GROUP_UPDATE:
  1419. -      repl_attr_all(0, A_SEEN, 0);
  1420. -      break;
  1421.         case K_READ_GROUP_THEN_SAME:
  1422.        break;
  1423.   
  1424.         case K_NEXT_GROUP_NO_UPDATE:
  1425.        menu_return(ME_NEXT);
  1426.   
  1427.         case K_PREVIOUS:
  1428. --- 1037,1068 ----
  1429.        if (nexta < n_articles) goto nextmenu;
  1430.        break;
  1431.   
  1432.         case K_READ_GROUP_THEN_SAME:
  1433. +      if (temp = mark_read_return) goto do_marked_by;
  1434.        break;
  1435.   
  1436.         case K_NEXT_GROUP_NO_UPDATE:
  1437. +      if (temp = mark_next_group) goto do_marked_by;
  1438. +      menu_return(ME_NEXT);
  1439. +       case K_READ_GROUP_UPDATE:
  1440. +      if (temp = mark_read_skip) break;
  1441. +       do_marked_by:
  1442. +      temp1 = 0; temp2 = n_articles;
  1443. +      switch (temp) {
  1444. +       case 1:
  1445. +          temp1 = firsta;
  1446. +       case 3:
  1447. +          temp2 = nexta;
  1448. +          break;
  1449. +       case 2:
  1450. +          temp2 = firsta - 1;
  1451. +          break;
  1452. +       case 4:
  1453. +          break;
  1454. +      }
  1455. +      repl_attr(temp1, temp2, 0, A_SEEN, 0);
  1456. +      if (k_cmd != K_NEXT_GROUP_NO_UPDATE) break;
  1457.        menu_return(ME_NEXT);
  1458.   
  1459.         case K_PREVIOUS:
  1460. ***************
  1461. *** 1103,1109 ****
  1462.         junk_another:
  1463.            if (cura < 0 || cura > numa) cura = 0;
  1464.            gotoxy(0, firstl + cura); fl;
  1465. !          
  1466.            switch (get_k_cmd()) {
  1467.             case K_JUNK_ARTICLES:
  1468.            junk_prompt++;    /* can be 0 */
  1469. --- 1136,1142 ----
  1470.         junk_another:
  1471.            if (cura < 0 || cura > numa) cura = 0;
  1472.            gotoxy(0, firstl + cura); fl;
  1473.            switch (get_k_cmd()) {
  1474.             case K_JUNK_ARTICLES:
  1475.            junk_prompt++;    /* can be 0 */
  1476. ***************
  1477. *** 1394,1403 ****
  1478. --- 1427,1438 ----
  1479.        ah = articles[firsta+cura];
  1480.   
  1481.        no_raw();
  1482. +      orig_attr = ah->attr;
  1483.        ah->attr = 0;
  1484.        menu_cmd = more(ah, MM_PREVIEW, prompt_line);
  1485.        if (menu_cmd == MC_MENU) {
  1486.            next_cura = cura;
  1487. +          if (ah->attr == 0) ah->attr = orig_attr;
  1488.            if (prompt_line < 0) goto redraw;
  1489.            mark();
  1490.            prompt_line = temp;
  1491. ***************
  1492. *** 1404,1410 ****
  1493.            goto build_prompt;
  1494.        }
  1495.   
  1496. !      if (preview_mark_read && ah->attr == 0) ah->attr = A_READ;
  1497.        if (prompt_line >= 0)
  1498.            mark();
  1499.        next_cura = ++cura;
  1500. --- 1439,1447 ----
  1501.            goto build_prompt;
  1502.        }
  1503.   
  1504. !      if (ah->attr == 0)
  1505. !          ah->attr = preview_mark_read ? A_READ : orig_attr;
  1506.        if (prompt_line >= 0)
  1507.            mark();
  1508.        next_cura = ++cura;
  1509. *** ./LAST/more.c    Wed May 16 11:22:46 1990
  1510. --- more.c    Mon May 21 14:02:04 1990
  1511. ***************
  1512. *** 595,602 ****
  1513.       }
  1514.       skip_char = NUL;
  1515.       if (overlap > 0) {
  1516. !         underline_line = linenum;
  1517. !         linenum -= overlap;
  1518.           goto next_page;
  1519.       }
  1520.       }
  1521. --- 595,602 ----
  1522.       }
  1523.       skip_char = NUL;
  1524.       if (overlap > 0) {
  1525. !         underline_line = linenum - 1;
  1526. !         linenum -= overlap + 1;
  1527.           goto next_page;
  1528.       }
  1529.       }
  1530. *** ./LAST/newsrc.c    Wed May 16 11:23:54 1990
  1531. --- newsrc.c    Wed May 16 21:49:04 1990
  1532. ***************
  1533. *** 989,994 ****
  1534. --- 989,999 ----
  1535.           if (gh->newsrc_line != NULL && gh->newsrc_orig != gh->newsrc_line)
  1536.           freeobj(gh->newsrc_line);
  1537.           gh->newsrc_line = NULL;
  1538. +         if (gh->newsrc_orig != NULL) dump_newsrc();
  1539. +         if (gh->select_line != NULL && gh->newsrc_orig != gh->select_line)
  1540. +         freeobj(gh->select_line);
  1541. +         gh->select_line = NULL;
  1542. +         if (gh->select_orig != NULL) dump_select();
  1543.           return;
  1544.       }
  1545.       
  1546. *** ./LAST/nngrab.sh    Wed May 16 11:22:50 1990
  1547. --- nngrab.sh    Fri May 18 22:59:11 1990
  1548. ***************
  1549. *** 8,20 ****
  1550.   
  1551.   trap "rm -f $TMP/nngrab$$" 0 1 2 15
  1552.   
  1553.   if [ ! $# -eq 1 ] ; then
  1554. !     echo "usage: $0 keyword-pattern"
  1555.       exit 1
  1556.   fi
  1557.   
  1558.   if [ -s $DB/subjects ] ; then
  1559. !     egrep "^[^:]*:.*$1" $DB/subjects |
  1560.       sed 's/^\([^:]*\):.*/\1/' |
  1561.       uniq > $TMP/nngrab$$
  1562.   
  1563. --- 8,28 ----
  1564.   
  1565.   trap "rm -f $TMP/nngrab$$" 0 1 2 15
  1566.   
  1567. + FOLDCASE=""
  1568. + if [ x"$1" = x"-c" ] ; then
  1569. +     FOLDCASE="-i"
  1570. +     shift
  1571. + fi
  1572.   if [ ! $# -eq 1 ] ; then
  1573. !     echo "usage: $0 [-c] keyword-pattern"
  1574.       exit 1
  1575.   fi
  1576.   
  1577. + KW="`echo "$1" | tr '[A-Z]' '[a-z]'`"
  1578.   if [ -s $DB/subjects ] ; then
  1579. !     egrep "^[^:]*:.*${KW}" $DB/subjects |
  1580.       sed 's/^\([^:]*\):.*/\1/' |
  1581.       uniq > $TMP/nngrab$$
  1582.   
  1583. ***************
  1584. *** 23,29 ****
  1585.           exit
  1586.       fi
  1587.   
  1588. !     $BIN/nn -Q -mxX -s/"$1" -G `cat $TMP/nngrab$$`
  1589.   else
  1590. !     $BIN/nn -Q -mxX -s/"$1" all
  1591.   fi
  1592. --- 31,37 ----
  1593.           exit
  1594.       fi
  1595.   
  1596. !     $BIN/nn -Q -mxX $FOLDCASE -s/"$1" -G `cat $TMP/nngrab$$`
  1597.   else
  1598. !     $BIN/nn -Q -mxX $FOLDCASE -s/"$1" all
  1599.   fi
  1600. *** ./LAST/pack_name.c    Mon Apr 23 18:25:58 1990
  1601. --- pack_name.c    Fri May 18 15:05:58 1990
  1602. ***************
  1603. *** 339,347 ****
  1604.           name++;
  1605.           continue;
  1606.           }
  1607. !         if (prev_space)
  1608. !         *p = TAB;
  1609. !         else {
  1610.           *p = '-';
  1611.           lname++;
  1612.           }
  1613. --- 339,348 ----
  1614.           name++;
  1615.           continue;
  1616.           }
  1617. !         if (prev_space) {
  1618. !         *p = NUL; break;    /* strip from " -" */
  1619. !         /* *p = TAB;     /* do not strip from " -" */
  1620. !         } else {
  1621.           *p = '-';
  1622.           lname++;
  1623.           }
  1624. *** ./LAST/patchlevel.h    Wed May 16 11:23:57 1990
  1625. --- patchlevel.h    Mon May 21 13:32:45 1990
  1626. ***************
  1627. *** 11,19 ****
  1628.    *    1990-03-03: Release 6.4beta    (FTP)
  1629.    *    1990-05-07: Release 6.4        (comp.sources.unix)
  1630.    *
  1631. !  *    1990-05-10: Patch #1 (6.4.1)
  1632. !  *    1990-05-15: Patch #2 (6.4.2)
  1633.    */
  1634.   
  1635. ! #define PATCHLEVEL 2
  1636.   
  1637. --- 11,20 ----
  1638.    *    1990-03-03: Release 6.4beta    (FTP)
  1639.    *    1990-05-07: Release 6.4        (comp.sources.unix)
  1640.    *
  1641. !  *    1990-05-10: Patch #1 (6.4.1) - HIGH
  1642. !  *    1990-05-15: Patch #2 (6.4.2) - HIGH
  1643. !  *    1990-05-21: Patch #3 (6.4.3) - HIGH
  1644.    */
  1645.   
  1646. ! #define PATCHLEVEL 3
  1647.   
  1648. *** ./LAST/save.c    Thu Apr 26 20:34:11 1990
  1649. --- save.c    Fri May 18 23:31:03 1990
  1650. ***************
  1651. *** 12,17 ****
  1652. --- 12,18 ----
  1653.   #include "news.h"
  1654.   
  1655.   export char *default_save_file = "+$F";
  1656. + export char *folder_save_file = NULL;
  1657.   export int suggest_save_file = 1;
  1658.   export char *unshar_header_file = "Unshar.Headers";
  1659.   export int  use_mail_folders = 0;
  1660. ***************
  1661. *** 183,189 ****
  1662.   
  1663.           save_name = current_group->save_file;
  1664.           if (save_name == NULL && suggest_save_file)
  1665. !         save_name = default_save_file;
  1666.           if (save_name != NULL) {
  1667.           if (!expand_file_name(name_buf, save_name, 2)) return NULL;
  1668.           save_name = name_buf;
  1669. --- 184,191 ----
  1670.   
  1671.           save_name = current_group->save_file;
  1672.           if (save_name == NULL && suggest_save_file)
  1673. !         save_name = (current_group->group_flag & G_FOLDER) ?
  1674. !             folder_save_file : default_save_file;
  1675.           if (save_name != NULL) {
  1676.           if (!expand_file_name(name_buf, save_name, 2)) return NULL;
  1677.           save_name = name_buf;
  1678. ***************
  1679. *** 193,203 ****
  1680.           if (save_name == NULL || *save_name == NUL) return NULL;
  1681.   
  1682.           if (save_name[1] == NUL && save_name[0] == '+')
  1683. !         save_name = default_save_file;
  1684.           else
  1685.           if (current_group->save_file == NULL ||
  1686.               strcmp(save_name, current_group->save_file))
  1687.               strcpy(last_input, save_name);
  1688.       }
  1689.   
  1690.       if (*save_name == '|') {
  1691. --- 195,207 ----
  1692.           if (save_name == NULL || *save_name == NUL) return NULL;
  1693.   
  1694.           if (save_name[1] == NUL && save_name[0] == '+')
  1695. !         save_name = (current_group->group_flag & G_FOLDER) ?
  1696. !             folder_save_file : default_save_file;
  1697.           else
  1698.           if (current_group->save_file == NULL ||
  1699.               strcmp(save_name, current_group->save_file))
  1700.               strcpy(last_input, save_name);
  1701. +         if (save_name == NULL || *save_name == NUL) return NULL;
  1702.       }
  1703.   
  1704.       if (*save_name == '|') {
  1705. *** ./LAST/sequence.c    Wed May 16 11:22:51 1990
  1706. --- sequence.c    Fri May 18 15:56:23 1990
  1707. ***************
  1708. *** 451,462 ****
  1709.           continue;
  1710.       }
  1711.   
  1712. !     if (file_exist(group, "fr")) {
  1713.           faked_entry(group, G_FOLDER);
  1714.           any++;
  1715.           continue;
  1716.       }
  1717.   
  1718.       if (*group == '+' || *group == '~') {
  1719.           char exp_file[FILENAME];
  1720.           group_header fake_group;
  1721. --- 451,463 ----
  1722.           continue;
  1723.       }
  1724.   
  1725. !     if (*group == '+' || *group == '~' || file_exist(group, "fr")) {
  1726.           faked_entry(group, G_FOLDER);
  1727.           any++;
  1728.           continue;
  1729.       }
  1730.   
  1731. + #ifdef NOT_DEF
  1732.       if (*group == '+' || *group == '~') {
  1733.           char exp_file[FILENAME];
  1734.           group_header fake_group;
  1735. ***************
  1736. *** 474,479 ****
  1737. --- 475,481 ----
  1738.           errors++;
  1739.           continue;
  1740.       }
  1741. + #endif
  1742.   
  1743.       found = 0;
  1744.       start_group_search(group);
  1745. *** ./LAST/term.c    Wed May 16 11:23:58 1990
  1746. --- term.c    Thu May 17 01:15:32 1990
  1747. ***************
  1748. *** 107,112 ****
  1749. --- 107,119 ----
  1750.   
  1751.   #else    /* V7/BSD TTY DRIVER */
  1752.   
  1753. + #ifdef FAKE_INTERRUPT
  1754. + #include <setjmp.h>
  1755. + extern jmp_buf fake_keyb_sig;
  1756. + extern int arm_fake_keyb_sig;
  1757. + #endif
  1758.   #include <sgtty.h>
  1759.   
  1760.   static struct sgttyb norm_tty, raw_tty;
  1761. ***************
  1762. *** 803,809 ****
  1763.       while (--n >= 0) {
  1764.       c = (key_type)*cp++;
  1765.   #else
  1766.       while ((n = read(0, (char *)&c, 1)) > 0) {
  1767.       c &= 0177;    /* done by ISTRIP on USG systems */
  1768.   #endif
  1769. --- 810,822 ----
  1770.       while (--n >= 0) {
  1771.       c = (key_type)*cp++;
  1772.   #else
  1773. ! #ifdef FAKE_INTERRUPT
  1774. !     if (setjmp(fake_keyb_sig)) {
  1775. !     arm_fake_keyb_sig = 0;
  1776. !     return K_interrupt;
  1777. !     }
  1778. !     arm_fake_keyb_sig = 1;
  1779. ! #endif
  1780.       while ((n = read(0, (char *)&c, 1)) > 0) {
  1781.       c &= 0177;    /* done by ISTRIP on USG systems */
  1782.   #endif
  1783. ***************
  1784. *** 830,836 ****
  1785. --- 843,853 ----
  1786.           first_key = c;
  1787.           alarm_on = 1;
  1788.           signal(SIGALRM, mk_timeout);
  1789. + #ifdef MICRO_ALARM
  1790.           MICRO_ALARM();
  1791. + #else
  1792. +         sleep(1);
  1793. + #endif
  1794.           }
  1795.   #endif
  1796.           key_cnt++;
  1797. ***************
  1798. *** 852,857 ****
  1799. --- 869,877 ----
  1800.   #endif
  1801.   
  1802.   #ifndef KEY_BURST
  1803. + #ifdef FAKE_INTERRUPT
  1804. +     arm_fake_keyb_sig = 0;
  1805. + #endif
  1806.       if (n < 0) {
  1807.       if (errno != EINTR) s_hangup++;
  1808.       return K_interrupt;
  1809. *** ./LAST/variable.c    Wed May 16 11:23:59 1990
  1810. --- variable.c    Mon May 21 17:08:29 1990
  1811. ***************
  1812. *** 18,23 ****
  1813. --- 18,24 ----
  1814.       *editor_program,
  1815.       *extra_mail_headers,
  1816.       *extra_news_headers,
  1817. +     *folder_save_file,
  1818.       *header_lines,
  1819.       *folder_directory,
  1820.       included_mark[],
  1821. ***************
  1822. *** 120,125 ****
  1823. --- 121,129 ----
  1824.       fmt_linenum,
  1825.       Lines,
  1826.       match_skip_prefix,
  1827. +     mark_next_group,
  1828. +     mark_read_return,
  1829. +     mark_read_skip,
  1830.       min_pv_window,
  1831.       new_group_action,
  1832.       newsrc_update_freq,
  1833. ***************
  1834. *** 229,234 ****
  1835. --- 233,239 ----
  1836.       "flow-control",        BOOL 0,        (char **)&flow_control,
  1837.       "flush-typeahead",        BOOL 0,        (char **)&flush_typeahead,
  1838.       "folder",            STR 2,        (char **)&folder_directory,
  1839. +     "folder-save-file",        STR 3,        (char **)&folder_save_file,
  1840.       "fsort",            BOOL 2,        (char **)&dont_sort_folders,
  1841.       "header-lines",        STR 0,        (char **)&header_lines,
  1842.       "help-key",            KEY 0,        (char **)&help_key,
  1843. ***************
  1844. *** 251,256 ****
  1845. --- 256,264 ----
  1846.       "mailer",            STR 0,        (char **)&mailer_program,
  1847.       "mailer-pipe-input",    BOOL 0,        (char **)&mailer_pipe_input,
  1848.       "mark-overlap",        BOOL 0,        (char **)&mark_overlap,
  1849. +     "marked-by-next-group",    INT 0,        (char **)&mark_next_group,
  1850. +     "marked-by-read-return",    INT 0,        (char **)&mark_read_return,
  1851. +     "marked-by-read-skip",    INT 0,        (char **)&mark_read_skip,
  1852.       "min-window",        INT 1,        (char **)&min_pv_window,
  1853.       "mmdf-format",        BOOL 0,        (char **)&use_mmdf_folders,
  1854.       "monitor",            BOOL 0,        (char **)&monitor_mode,
  1855. ***************
  1856. *** 531,536 ****
  1857. --- 539,590 ----
  1858.   }
  1859.   
  1860.   
  1861. + static char *var_value(var, tag)
  1862. + register struct variable_defs *var;
  1863. + char *tag;
  1864. + {
  1865. +     static char ival[16];
  1866. +     register char *str;
  1867. +     register int b;
  1868. +     *tag = var_on_stack(var) ? '>' :
  1869. +     (var->var_flags & V_MODIFIED) ? '*' : ' ';
  1870. +     switch (VAR_TYPE) {
  1871. +      case V_STRING:
  1872. +     str = (VAR_OP == 1) ? CBUF_VAR : STR_VAR;
  1873. +     break;
  1874. +      case V_BOOLEAN:
  1875. +     b = BOOL_VAR;
  1876. +     if (VAR_OP == 2 || VAR_OP == 4) b = !b;
  1877. +     str = b ? "on" : "off";
  1878. +     break;
  1879. +      case V_INTEGER:
  1880. +     sprintf(ival, "%d", INT_VAR);
  1881. +     str = ival;
  1882. +     break;
  1883. +     
  1884. +      case V_KEY:
  1885. +     str = key_name(KEY_VAR);
  1886. +     break;
  1887. +      case V_SPECIAL:
  1888. +     str = "UNDEF";
  1889. +     switch (VAR_OP) {
  1890. +      case 2:
  1891. +         if (!also_read_articles) break;
  1892. +         sprintf(ival, "%d", article_limit);
  1893. +         str = ival;
  1894. +         break;
  1895. +     }
  1896. +     break;
  1897. +     }
  1898. +     if (str == NULL) str = "NULL";
  1899. +     return str;
  1900. + }
  1901.   test_variable(expr)
  1902.   char *expr;
  1903.   {
  1904. ***************
  1905. *** 865,868 ****
  1906. --- 919,938 ----
  1907.   
  1908.   out:
  1909.       pg_end();
  1910. + }
  1911. + print_variable_config(f, all)
  1912. + FILE *f;
  1913. + int all;
  1914. + {
  1915. +     register struct variable_defs *var;
  1916. +     char *str, tag[2];
  1917. +     register int b;
  1918. +     
  1919. +     tag[1] = NUL;
  1920. +     for (var = variables; var < &variables[TABLE_SIZE]; var++) {
  1921. +     if (!all && (var->var_flags & V_MODIFIED) == 0) continue;
  1922. +     str = var_value(var, tag);
  1923. +     fprintf(f, "%s%s='%s'\n", all ? tag : "", var->var_name, str);
  1924. +     }
  1925.   }
  1926.